package com.bor.gb.rest.configuration;

import com.bor.gb.db.domain.User;
import com.bor.gb.db.repositories.UserRepositoryCustom;
import com.bor.gb.db.services.UserService;
import com.bor.gb.rest.security.UserContextDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * Created by bor on 10/12/14.
 */
@Configuration
@EnableWebSecurity
public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepositoryCustom userRepository;

    @Autowired
    private UserService userService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(new AuthenticationProvider() {

            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String email = authentication.getName();
                String password = authentication.getCredentials().toString();

                User user = userService.login(email, password);
                if ( user != null) {

                    UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(email, "dmpass", user.getAuthorities());
                    auth.setDetails(new UserContextDetails( user.getId(), user.getEmail()));
                    return auth;
                }else{
                    throw new UsernameNotFoundException("Username or login is incorrect");
                }
            }

            @Override
            public boolean supports(Class<?> authentication) {
                return authentication.equals(UsernamePasswordAuthenticationToken.class);
            }
        });

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**

         *  TODO enable CSRF after support implementing
         */

       http.csrf().disable();

       http.authorizeRequests()
                .antMatchers("/gb/v01/user/signup").permitAll()
                .antMatchers("/gb/v01/user/session").permitAll()
                .antMatchers("/gb/v01/user/activate").permitAll()
                .antMatchers("/gb/v01/guide/search").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/gb/v01/user/signin")
                .failureUrl("/gb/v01/user/session")
                .defaultSuccessUrl("/gb/v01/user/session")
                .permitAll()
                .and()
                .logout().logoutUrl("/gb/v01/user/logout")
                .logoutSuccessUrl("/gb/v01/user/session")
                .permitAll();
    }
}
